package com.bys.admin.system.controller;


import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bys.admin.system.controller.vo.CodegenTablePreviewResVO;
import com.bys.admin.system.controller.vo.CodegenTableSaveVo;
import com.bys.admin.system.controller.vo.DataBaseTableResVo;
import com.bys.admin.system.convert.codegenTable.CodegenTableConvert;
import com.bys.admin.system.entity.SysCodegenTable;
import com.bys.admin.system.service.ISysCodegenTableService;
import com.bys.response.R;
import com.bys.vo.PageVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import javax.validation.Valid;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.bys.util.FileTypeUtils.writeAttachment;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author bys
 * @since 2025-02-19
 */
@Tag(name = "代码生成")
@RestController
@RequestMapping("/system/sys-codegen-table")
@Validated
public class SysCodegenTableController {

    @Resource
    private ISysCodegenTableService sysCodegenTableService;

    @Operation(summary = "下载生成代码")
    @PostMapping
            ("/download/{tableId}")
    public void downloadCodegen(@PathVariable Long tableId,
                                HttpServletResponse response) throws IOException {
        // 生成代码
        Map<String, String> codes = sysCodegenTableService.generationCodes(tableId);
        // 构建 zip 包
        String[] paths = codes.keySet().toArray(new String[0]);
        ByteArrayInputStream[] ins = codes.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipUtil.zip(outputStream, paths, ins);
        // 输出
        writeAttachment(response, "codegen.zip", outputStream.toByteArray());
    }


    @Operation(summary = "基于数据库的表结构，同步数据库的表和字段")
    @PutMapping("/sync-from-db/{tableId}")
    public R<Object>  syncCodegenFormDb(@PathVariable Long tableId){
        sysCodegenTableService.syncCodegenFromDB(tableId);
        return R.success(Boolean.TRUE);
    }

    @Operation(summary = "删除代码生成器的表和字段")
    @DeleteMapping("/delete/{tableId}")
    public R<Boolean> deleteCodegen(@PathVariable Long tableId){
        sysCodegenTableService.deleteTable(tableId);
        return R.success(Boolean.TRUE);

    }
    @Operation(summary = "预览生成代码")
    @GetMapping("/preview/{tableId}")
    public R<List<CodegenTablePreviewResVO>> previewCodegen(@PathVariable Long tableId){
        return  R.success(CodegenTableConvert.INSTANCE.convertPreviewVo(sysCodegenTableService.generationCodes(tableId)));
    }

    @Operation(summary = "创建代码生成器的表和字段")
    @PostMapping("/create-list")
    public R<Boolean> createCodegenTable(@RequestBody @Valid CodegenTableSaveVo codegenTableSaveVo){
        sysCodegenTableService.createCodegenTable(codegenTableSaveVo);
        return  R.success(Boolean.TRUE);
    }


    @Operation( summary = "获得数据库表", description = "会过滤掉已经导入 Codegen 的表")
    @GetMapping("/db/list")
    public R<List<DataBaseTableResVo>>  getDataBaseList(Long dataResourceId, String tableName, String tableComment ){
        List<DataBaseTableResVo> resData =  sysCodegenTableService.getDataBaseList(dataResourceId,tableName,tableComment);
        return R.success(resData);
    }



    @Operation(summary = "分页查询")
    @GetMapping("/page")
    public R<Page<SysCodegenTable>> page(PageVo pageVo){
        Page<SysCodegenTable> page = sysCodegenTableService.page(new Page<SysCodegenTable>(pageVo.getPageNo(), pageVo.getPageSize()),new LambdaQueryWrapper<SysCodegenTable>().orderByDesc(SysCodegenTable::getCreateTime));
        return R.success(page);
    }

}
